﻿using Castle.DynamicProxy;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JGSY.SerialCommunication.UpperComputer.Core.AOP.ThirdPartyLibrary
{
    /***
     * 实现 【标记（Flag）接口 + Castle 】复杂拦截逻辑 
     * 1、定义拦截器标记接口
     * 2、定义自定义拦截器属性
     * 3、实现 IInterceptor 接口的日志拦截器 
     * 4、用于标记代理对象的混入类
     * 5、AOP代理工厂
     * 6、选择性拦截器
     * 7、实现标记接口的服务类  方法必须是  virtual  类代理（继承方式）：必须使用 virtual 方法
     *          优化7方案 【 接口代理：无需 virtual，但需通过接口调用方法】
     *  // 定义接口
     *  public interface IUserService : IInterceptableFlag{ string GetUserName(int id);}
     *     // 实现类（方法无需 virtual）
     *   public class UserService : IUserService {
     *    [Log]
     *    public string GetUserName(int id) => "测试用户";  }
     *
     *  创建接口代理
     *  var service = Generator.CreateInterfaceProxyWithTargetInterface(
     *    typeof(IUserService),
     *    new UserService(),
     *    new SelectiveInterceptor()
     *) as IUserService;
     *  
     * */

    /// <summary>
    /// 1、定义拦截器标记接口
    /// </summary>
    public interface IInterceptableFlag { }

    /// <summary>
    /// 2、定义自定义拦截器属性
    /// </summary>
    [AttributeUsage(AttributeTargets.Method)]
    public class LogFlagAttribute : Attribute { }

    /// <summary>
    ///  3、 实现 IInterceptor 接口的日志拦截器
    /// </summary> 
    public class LogIInterceptorCastleDynamicProxyFlag :  IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            // 前置处理
            Console.WriteLine($"LogAspectCastleDynamicProxyAttribute方法执行前: {invocation.Method.Name}");
            Console.WriteLine($"参数: {string.Join(", ", invocation.Arguments)}");
            var stopwatch = Stopwatch.StartNew();
            try
            {

                // 调用实际方法
                invocation.Proceed();
                Console.WriteLine($"方法执行后: 返回值 {invocation.ReturnValue}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"方法异常: {ex.Message}");
                throw;
            }
            finally
            {
                stopwatch.Stop();

                // 后置处理
                //Console.WriteLine($"方法执行后: 返回值 {invocation.ReturnValue}");
                Console.WriteLine($"方法 {invocation.Method.Name} 执行完成");
                Console.WriteLine($"返回值: {invocation.ReturnValue ?? "null"}");
                Console.WriteLine($"执行时间: {stopwatch.ElapsedMilliseconds} ms");
                Console.WriteLine("----------------------------------------");
            }
        }
    }
    /// <summary>
    /// 4、用于标记代理对象的混入类
    /// </summary>
    public class InterceptableFlagMixin : IInterceptableFlag { }


    /// <summary>
    /// 5、AOP代理工厂
    /// </summary>
    public static class ProxyFactoryFlag
    {
        private static readonly ProxyGenerator Generator = new ProxyGenerator();

        public static T CreateProxy<T>() where T : class, IInterceptableFlag
        {
            var options = new ProxyGenerationOptions();
            options.AddMixinInstance(new InterceptableFlagMixin());

            return Generator.CreateClassProxy<T>(
                options,
                new SelectiveInterceptorFlag()
            );
        }
    }
    /// <summary>
    /// 6、选择性拦截器
    /// </summary>
    public class SelectiveInterceptorFlag : IInterceptor
    {
        private readonly LogIInterceptorCastleDynamicProxyFlag _logInterceptor = new LogIInterceptorCastleDynamicProxyFlag();

        public void Intercept(IInvocation invocation)
        {
            var methodHasLogAttribute = invocation?.MethodInvocationTarget?
                .GetCustomAttributes(typeof(LogFlagAttribute), true)
                .Length > 0;

            if (methodHasLogAttribute)
            {
                _logInterceptor.Intercept(invocation);
            }
            else
            {
                invocation?.Proceed();
            }
        }
    }

}
